1. Mongodb 기초

특징

Mongodb의 경우 json 형식으로 데이터를 저장하는 데이터베이스입니다.

특징

  • 컬렉션에 대한 정의가 필요하지 않다.
  • Json형식으로 쿼리 작성 가능
  • _Id 필드가 Primary key역할을 함.
$ mongosh
> db.user.insertOne({uid: 'admin', upw: 'secretpassword'})
{ acknowledged: true, insertedId: ObjectId("5e71d395b050a2511caa827d")}
> db.user.find({uid: 'admin'})
[{ "_id" : ObjectId("5e71d395b050a2511caa827d"), "uid" : "admin", "upw" : "secretpassword" }]

collection이란?

> Mongodb에서 컬렉션은 RDBMS의 Table과 같은 역할 합니다.

MongoDB 연산자

Comparison

NameDescription
$eq지정된 값과 같은 값을 찾습니다. (equal)
$in배열 안의 값들과 일치하는 값을 찾습니다. (in)
$ne지정된 값과 같지 않은 값을 찾습니다. (not equal)
$nin배열 안의 값들과 일치하지 않는 값을 찾습니다. (not in)

Logical

NameDescription
$and논리적 AND, 각각의 쿼리를 모두 만족하는 문서가 반환됩니다.
$not쿼리 식의 효과를 반전시킵니다. 쿼리 식과 일치하지 않는 문서를 반환합니다.
$nor논리적 NOR, 각각의 쿼리를 모두 만족하지 않는 문서가 반환됩니다.
$or논리적 OR, 각각의 쿼리 중 하나 이상 만족하는 문서가 반환됩니다.

Element

NameDescription
$exists지정된 필드가 있는 문서를 찾습니다.
$type지정된 필드가 지정된 유형인 문서를 선택합니다.

Evaluation

NameDescription
$expr쿼리 언어 내에서 집계 식을 사용할 수 있습니다.
$regex지정된 정규식과 일치하는 문서를 선택합니다.
$text지정된 텍스트를 검색합니다.

기본 문법

SELECT

mongodb에서는 find() 함수를 통해서 특정 데이터를 조회 할 수 있습니다.

# SELECT * FROM account;
db.account.find()
// SELECT * FROM account WHERE user_id="admin";
db.account.find(
	{user_id: "admin"}
)
// SELECT user_idx FROM account WHERE user_id="admin";
db.account.find(
	{user_id: "admin"},
	{user_idx:1, _id:0}
)

INSERT

삽입은 insertOne() 함수를 통해서 삽입이 가능합니다.

// INSERT INTO account(user_id, user_pw) VALUES ("guest", "guest");
db.account.insertOne(
	{user_id: "guest", user_pw: "guest"}
)

DELETE

remove() 함수는 데이터 삭제를 의미합니다.

// DELETE FROM account;
db.account().remove()
// DELETE FROM account WHERE user_id="guest";
db.account.remove(
	{user_id: "guest"}
)

UPDATE

UPDATE account SET user_id="guest2" WHERE user_idx=2;
db.account.updateOne(
  { user_idx: 2 },
  { $set: { user_id: "guest2" } }
)

2. Mongodb NoSQL Injection

const express = require('express');
const app = express();
const mongoose = require('mongoose');
const db = mongoose.connection;
mongoose.connect('mongodb://localhost:27017/', { useNewUrlParser: true, useUnifiedTopology: true });
app.get('/query', function(req,res) {
    db.collection('user').find({
        'uid': req.query.uid,
        'upw': req.query.upw
    }).toArray(function(err, result) {
        if (err) throw err;
        res.send(result);
  });
});
const server = app.listen(3000, function(){
    console.log('app.listen');
});

위 코드의 경우 오브젝트 타입의 값을 입력할 수 있다면 연산자를 사용할 수 있습니다. 따라서 학습한 $ne 연산자는 not equal의 약자로 데이터와 일치하지 않는 데이터를 반환합니다.

http://localhost:3000/query?uid[$ne]=a&upw[$ne]=a
=> [{"_id":"5ebb81732b75911dbcad8a19","uid":"admin","upw":"secretpassword"}]

NOTE

> 만약 이렇게 [$ne]를 qs에 담아서 보내고 싶다면  app.use(express.urlencoded({extended:false}));라는 설정이 되어 있어야합니다.

3. Blind NoSQL Injection

MongoDB에서는 $regex, $where 연산자를 사용해 Blind NoSQL Injection을 할 수 있습니다. 아래 표는 각 연산자에 대해서 설명한 표입니다. 더 많은 연산자는 아래 첨부한 공식 문서를 통해 확인할 수 있습니다.

NameDescription
$expr쿼리 언어 내에서 집계 식을 사용할 수 있습니다.
$regex지정된 정규식과 일치하는 문서를 선택합니다.
$text지정된 텍스트를 검색합니다.
$whereJavaScript 표현식을 만족하는 문서와 일치합니다.